﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Security;

namespace SCRUM.Core.BusinessObjects
{
	/// <summary>
	/// User entity
	/// </summary>
    [Serializable()]
    public class User : MembershipUser, IEqualityComparer<User>
    {
        /// <summary>
        /// Gets or sets the ID.
        /// </summary>
        /// <value>The ID.</value>
        public int ID { get; set; }

        /// <summary>
        /// Gets or sets the login.
        /// </summary>
        /// <value>The login.</value>
        public string Login { get; set; }

        /// <summary>
        /// Gets or sets the password.
        /// </summary>
        /// <value>The password.</value>
        public string Password { get; set; }

        /// <summary>
        /// Gets or sets activity of user.
        /// </summary>
        /// <value>active/inactive</value>
        public bool Enabled { get; set; }

        /// <summary>
        /// Gets or sets full name.
        /// </summary>
        /// <value>Full Name</value>
        public string FullName { get; set; }

        /// <summary>
        /// Gets or sets the e-mail address for the membership user.
        /// </summary>
        /// <value></value>
        /// <returns>
        /// The e-mail address for the membership user.
        /// </returns>
        public string Email { get; set; }

        /// <summary>
        /// Gets or sets the Instant messageing contact.
        /// </summary>
        /// <value>The IM.</value>
        public string IM { get; set; }

        /// <summary>
        /// Gets or sets the telephone.
        /// </summary>
        /// <value>The telephone.</value>
        public string Telephone { get; set; }

        /// <summary>
        /// Gets or sets the admin's description of user
        /// </summary>
        /// <value>The description.</value>
        public string Description { get; set; }

        /// <summary>
        /// Gets or sets the default role ID for user.
        /// </summary>
        /// <value>The default role ID.</value>
        public int DefaultRoleID { get; set; }

        /// <summary>
        /// Gets or sets the velocity.
        /// </summary>
        /// <value>The velocity.</value>
        public int Velocity { get; set; }

		/// <summary>
		/// Initializes a new instance of the <see cref="User"/> class.
		/// </summary>
        public User() 
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="User"/> class.
		/// </summary>
		/// <param name="id">The id.</param>
		/// <param name="login">The login.</param>
		/// <param name="password">The password.</param>
		/// <param name="fullName">The full name.</param>
		/// <param name="email">The email.</param>
		/// <param name="enabled">if set to <c>true</c> [enabled].</param>
		/// <param name="telephone">The telephone.</param>
		/// <param name="im">The im.</param>
		/// <param name="description">The description.</param>
		/// <param name="defaultRoleID">The default role ID.</param>
		/// <param name="velocity">The velocity.</param>
        public User(int id, string login, string password, string fullName, string email, 
            bool enabled, string telephone, string im, string description, int defaultRoleID, int velocity)
        {
            this.ID = id;
            this.Login = login;
            this.Password = password;
            this.FullName = fullName;
            this.Email = email;
            this.Enabled = enabled;
            this.Telephone = telephone;
            this.IM = im;
            this.Description = description;
            this.DefaultRoleID = defaultRoleID;
            this.Velocity = velocity;
        }

        /// <summary>
        /// Role of the user.
        /// </summary>
        protected Role role;

        /// <summary>
        /// Gets or sets the role.
        /// </summary>
        /// <value>The role.</value>
        public Role Role 
        {
            get
            {
                if (this.role == null)
                {
                    this.role = DAO.DAORole.GetRoleForUser(this);
                }
                return this.role;
            }
            set 
			{ 
				this.role = value; 
			} 
        }

        /// <summary>
        /// Team of the user.
        /// </summary>
        protected IList<Team> team;

        /// <summary>
        /// Gets or sets the team.
        /// </summary>
        /// <value>The team.</value>
        public IList<Team> Team
        {
            get
            {
                if (this.team == null)
                {
                    this.team = DAO.DAOTeam.GetTeamForUser(this);
                }
                return this.team;
            }
            set { this.team = value; }
        }

        /// <summary>
        /// Returns the user name for the membership user.
        /// </summary>
        /// <returns>
        /// The <see cref="P:System.Web.Security.MembershipUser.UserName"/> for the membership user.
        /// </returns>
        public override string ToString()
        {
            return String.Format("{0} | {1}", this.Login, this.FullName);
        }

        /// <summary>
        /// Gets the name + login for user
        /// </summary>
        /// <value>The name of the extended user.</value>
        public string ExtendedUserName
        {
            get
            {
                return String.Format("{0} ({1})", this.FullName, this.Login );
            }
        }

        /// <summary>
        /// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
        /// </summary>
        /// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
        /// <returns>
        /// 	<c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
        /// </returns>
        /// <exception cref="T:System.NullReferenceException">
        /// The <paramref name="obj"/> parameter is null.
        /// </exception>
        public override bool Equals(object obj)
        {
            return (obj as User).ID == this.ID;
        }

		/// <summary>
		/// Returns a hash code for this instance.
		/// </summary>
		/// <returns>
		/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
		/// </returns>
		public override int GetHashCode()
		{
			return base.GetHashCode();
		}
    
        #region IEqualityComparer<User> Members

        /// <summary>
        /// Determines whether the specified objects are equal.
        /// </summary>
        /// <param name="x">The first object of type <paramref name="T"/> to compare.</param>
        /// <param name="y">The second object of type <paramref name="T"/> to compare.</param>
        /// <returns>
        /// true if the specified objects are equal; otherwise, false.
        /// </returns>
        public bool Equals(User x, User y)
        {
            return x.ID == y.ID;
        }

        /// <summary>
        /// Returns a hash code for this instance.
        /// </summary>
        /// <param name="obj">The obj.</param>
        /// <returns>
        /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
        /// </returns>
        /// <exception cref="T:System.ArgumentNullException">
        /// The type of <paramref name="obj"/> is a reference type and <paramref name="obj"/> is null.
        /// </exception>
        public int GetHashCode(User obj)
        {
            return obj.GetHashCode();
        }

        #endregion
	}
}
